home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s2.arc / PIBANSIA.MOD < prev    next >
Text File  |  1987-09-29  |  57KB  |  1,366 lines

  1. (*----------------------------------------------------------------------*)
  2. (*                Emulate_ANSI  -- Controls VT100 emulation             *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Emulate_ANSI( VT100_Allowed : BOOLEAN );
  6.  
  7. (*----------------------------------------------------------------------*)
  8. (*                                                                      *)
  9. (*    Procedure: Emulate_ANSI                                           *)
  10. (*                                                                      *)
  11. (*    Purpose:   Controls ANSI terminal emulation                       *)
  12. (*                                                                      *)
  13. (*    Calling Sequence:                                                 *)
  14. (*                                                                      *)
  15. (*       Emulate_ANSI( VT100_allowed );                                 *)
  16. (*                                                                      *)
  17. (*          VT100_allowed --- TRUE to interpret private DEC sequences   *)
  18. (*                                                                      *)
  19. (*    Remarks:                                                          *)
  20. (*                                                                      *)
  21. (*       The ANSI and VT100 emulation are partly based upon TMODEM      *)
  22. (*       by Paul Meiners and partly upon ISP100 by Tim Krauskopf.       *)
  23. (*                                                                      *)
  24. (*       VT100/ANSI commands are interpreted directly by these          *)
  25. (*       routines -- the ANSI.SYS driver is not required and should     *)
  26. (*       probably not be used, as it will result in an unnecessary      *)
  27. (*       performance degradation.                                       *)
  28. (*                                                                      *)
  29. (*       This is by no means a complete VT100 or Ansi emulation.  It    *)
  30. (*       works well enough so that the full-screen editors EDT under    *)
  31. (*       VAX/VMS and FSE under CDC/NOS will perform properly.  That was *)
  32. (*       my primary intention.  You may want to add code to emulate     *)
  33. (*       other VT100/VT102/VT103/VT131 features not found here.  If you *)
  34. (*       do, please send me back a copy so that I can add your upgrades *)
  35. (*       to future releases of PibTerm.                                 *)
  36. (*                                                                      *)
  37. (*       ANSI/BBS mode assumes 25 lines on the screen.  VT100 mode      *)
  38. (*       assumes only has 24.                                           *)
  39. (*                                                                      *)
  40. (*       The following variables are of central interest in the         *)
  41. (*       emulation:                                                     *)
  42. (*                                                                      *)
  43. (*         Escape_Mode     --- TRUE if processing escape sequence       *)
  44. (*         Escape_Type     --- Type of escape sequence being processed  *)
  45. (*         Escape_Number   --- Number of numeric parameters in escape   *)
  46. (*                             sequence                                 *)
  47. (*         Escape_Register --- array of numeric parameters in escape    *)
  48. (*                             sequence                                 *)
  49. (*         Escape_Str      --- stores string of escape text; used to    *)
  50. (*                             gather up a musical score for BBS Ansi.  *)
  51. (*                                                                      *)
  52. (*----------------------------------------------------------------------*)
  53.  
  54. VAR
  55.    Comm_Ch             : CHAR        (* Character read from comm port   *);
  56.    Double_Ch           : CHAR        (* Character for double-width mode *);
  57.    Kbd_Ch              : CHAR        (* Character read from keyboard    *);
  58.    Done                : BOOLEAN     (* TRUE to stop PIBTERM            *);
  59.    B                   : BOOLEAN     (* General purpose flag            *);
  60.    Graph_Ch            : BYTE        (* Graphics character              *);
  61.    Itab                : BYTE        (* Tab stop                        *);
  62.    Tabcol              : BYTE        (* Tab column                      *);
  63.    Print_Line          : AnyStr      (* Line to print if print mode on  *);
  64.    Local_Save          : Saved_Screen_Ptr;
  65.    Reset_Attr          : BOOLEAN;
  66.    SVal                : STRING[10];
  67.    Do_Graphics_Mode    : BOOLEAN;
  68.    ClrScr_Request      : BOOLEAN;
  69.    VT100_G0_Set        : CHAR;
  70.    VT100_G1_Set        : CHAR;
  71.    VT100_G0_State      : BOOLEAN;
  72.    Save_Dos_Con        : BOOLEAN;
  73.    Save_Do_Status      : BOOLEAN;
  74.  
  75. VAR                                  (* Special output characters *)
  76.  
  77.    Special_Comm  : ARRAY[0..255] OF BOOLEAN;
  78.  
  79.                                      (* VT100 tabs stops                *)
  80. VAR
  81.    Number_VT100_Tabs : INTEGER;
  82.  
  83.    VT100_Tabs:  Tab_Stop_Vector;
  84.  
  85. (*----------------------------------------------------------------------*)
  86. (*      Ansi_Check_Line_Attributes --- Checks attributes for a line     *)
  87. (*----------------------------------------------------------------------*)
  88.  
  89. PROCEDURE Ansi_Check_Line_Attributes( Y: INTEGER );
  90.  
  91. BEGIN (* Ansi_Check_Line_Attributes *)
  92.  
  93.    CASE Line_Attributes[ Y ] OF
  94.       3: Skip_All_Mode     := ON;  (* Skip Top Half of Line              *)
  95.       4: (* Double_Width_Mode := ON *);
  96.       6: (* Double_Width_Mode := ON *);
  97.       ELSE
  98.          Skip_All_Mode     := OFF;
  99.          Double_Width_Mode := OFF;
  100.    END (* CASE *);
  101.  
  102. END   (* Ansi_Check_Line_Attributes *);
  103.  
  104. (*----------------------------------------------------------------------*)
  105. (*       Ansi_Scroll_Attributes --- Scrolls attributes for lines        *)
  106. (*----------------------------------------------------------------------*)
  107.  
  108. PROCEDURE Ansi_Scroll_Attributes( Lines, From : Integer );
  109.  
  110. VAR
  111.    I: INTEGER;
  112.  
  113. BEGIN (* Ansi_Scroll_Attributes *)
  114.  
  115.    IF ( Lines > 0 ) THEN           (* Move down in attr. array *)
  116.       BEGIN
  117.          MOVE( Line_Attributes[ From ], Line_Attributes[ From + Lines ],
  118.                Bottom_Scroll - Top_Scroll - Lines + 1);
  119.          FOR I := 0 TO Lines DO
  120.             Line_Attributes[ From + I ] := 0;
  121.       END
  122.    ELSE                            (* Move up in the attr. array *)
  123.       BEGIN
  124.          MOVE( Line_Attributes[From + Lines], Line_Attributes[ From ],
  125.                Bottom_Scroll - Top_Scroll - Lines + 1);
  126.          FOR I := 0 TO Lines DO
  127.             Line_Attributes [Bottom_Scroll - I] := 0;
  128.       END;
  129.                                    (* Ensure last column hit is set FALSE *)
  130.    Last_Column_Hit := FALSE;
  131.  
  132. END   (* Ansi_Scroll_Attributes *);
  133.  
  134. (*----------------------------------------------------------------------*)
  135. (*            Set_Cursor --- Set cursor to specified screen location    *)
  136. (*----------------------------------------------------------------------*)
  137.  
  138. PROCEDURE Set_Cursor( X , Y : INTEGER );
  139.  
  140. BEGIN (* Set_Cursor *)
  141.  
  142.    Ansi_Check_Line_Attributes( Y );
  143.  
  144.    IF Double_Width_Mode THEN
  145.       GoToXY( 2 * X - 1 , Y )
  146.    ELSE
  147.       GoToXY( X , Y );
  148.  
  149. END   (* Set_Cursor *);
  150.  
  151. (*----------------------------------------------------------------------*)
  152. (*             Ansi_Set_Graphics --- Set graphics display               *)
  153. (*----------------------------------------------------------------------*)
  154.  
  155. PROCEDURE Ansi_Set_Graphics;
  156.  
  157. (*----------------------------------------------------------------------*)
  158. (*                                                                      *)
  159. (*     Procedure: Ansi_Set_Graphics                                     *)
  160. (*                                                                      *)
  161. (*     Purpose:   Sets graphics rendition modes for ANSI/VT100          *)
  162. (*                                                                      *)
  163. (*     Calling Sequence:                                                *)
  164. (*                                                                      *)
  165. (*        Ansi_Set_Graphics;                                            *)
  166. (*                                                                      *)
  167. (*     Calls:                                                           *)
  168. (*                                                                      *)
  169. (*        Set_Global_Colors                                             *)
  170. (*                                                                      *)
  171. (*     Called by:  VT100_Process_Escape                                 *)
  172. (*                 Ansi_Process_Escape                                  *)
  173. (*                                                                      *)
  174. (*----------------------------------------------------------------------*)
  175.  
  176. VAR
  177.    I     : INTEGER;
  178.    J     : INTEGER;
  179.  
  180. BEGIN (* Ansi_Set_Graphics *)
  181.  
  182.    IF ( Escape_Number = 0 ) THEN
  183.       BEGIN
  184.          Escape_Number      := 1;
  185.          Escape_Register[1] := 0;
  186.       END;
  187.  
  188.    FOR I := 1 TO Escape_Number DO
  189.       BEGIN
  190.  
  191.          CASE Escape_Register[I] OF
  192.  
  193.             0 : BEGIN
  194.                    IF VT100_Allowed THEN
  195.                       BEGIN
  196.                          FG := VT100_ForeGround_Color;
  197.                          BG := VT100_BackGround_Color;
  198.                          Set_Border_Color( BG );
  199.                       END
  200.                    ELSE
  201.                       BEGIN
  202.                          FG := LightGray;
  203.                          BG := Black;
  204.                          Set_Border_Color( Black );
  205.                       END;
  206.                    Bolding_On  := FALSE;
  207.                    Blinking_On := FALSE;
  208.                 END;
  209.  
  210.             1 : BEGIN
  211.                    IF VT100_Allowed THEN
  212.                       FG          := Ansi_Bold_Color
  213.                    ELSE
  214.                       FG          := Bold_Colors[ FG ];
  215.                    Bolding_On  := TRUE;
  216.                 END;
  217.  
  218.             4 : BEGIN
  219.                                    (* NOTE: In mono mode BLUE will    *)
  220.                                    (* correctly produce an underline. *)
  221.  
  222.                    FG := Ansi_Underline_Color;
  223.  
  224.                 END;
  225.  
  226.             5 : Blinking_On := TRUE;
  227.  
  228.             7 : BEGIN
  229.                    IF VT100_Allowed THEN
  230.                       BEGIN
  231.                          FG := Ansi_BackGround_Color;
  232.                          IF Bolding_On THEN
  233.                             BG := Ansi_Bold_Color
  234.                          ELSE
  235.                             BG := Ansi_ForeGround_Color;
  236.                       END
  237.                    ELSE
  238.                       BEGIN
  239.                          FG := Black;
  240.                          BG := LightGray;
  241.                       END
  242.                 END;
  243.  
  244.             8 : FG := BG;
  245.  
  246.         30..37: IF ( Text_Mode = C80 ) THEN
  247.                    BEGIN
  248.                       IF Bolding_On THEN
  249.                          FG := Bold_Colors_2[ Escape_Register[I] - 30 ]
  250.                       ELSE
  251.                          FG := Normal_Colors_2[ Escape_Register[I] - 30 ];
  252.                    END;
  253.  
  254.         40..47: IF ( Text_Mode = C80 ) THEN
  255.                    BEGIN
  256.                       IF Bolding_On THEN
  257.                          BG := Bold_Colors_2[ Escape_Register[I] - 40 ]
  258.                       ELSE
  259.                          BG := Normal_Colors_2[ Escape_Register[I] - 40 ];
  260.                    END;
  261.  
  262.          END (* CASE *);
  263.  
  264.       END;
  265.                                    (* Change the colors *)
  266.    IF Blinking_On THEN
  267.       FG := FG + Blink;
  268.  
  269.    Set_Global_Colors( FG , BG );
  270.  
  271. END   (* Ansi_Set_Graphics *);
  272.  
  273. (*----------------------------------------------------------------------*)
  274. (*             Ansi_Set_Cursor --- Set cursor position                  *)
  275. (*----------------------------------------------------------------------*)
  276.  
  277. PROCEDURE Ansi_Set_Cursor;
  278.  
  279. (*----------------------------------------------------------------------*)
  280. (*                                                                      *)
  281. (*     Procedure: Ansi_Set_Cursor                                       *)
  282. (*                                                                      *)
  283. (*     Purpose:   Sets cursor position                                  *)
  284. (*                                                                      *)
  285. (*     Calling Sequence:                                                *)
  286. (*                                                                      *)
  287. (*        Ansi_Set_Cursor;                                              *)
  288. (*                                                                      *)
  289. (*     Calls:                                                           *)
  290. (*                                                                      *)
  291. (*        Max                                                           *)
  292. (*        Min                                                           *)
  293. (*        UpperLeft                                                     *)
  294. (*        Set_Cursor                                                    *)
  295. (*                                                                      *)
  296. (*     Called by:  VT100_Process_Escape                                 *)
  297. (*                 Ansi_Process_Escape                                  *)
  298. (*                                                                      *)
  299. (*----------------------------------------------------------------------*)
  300.  
  301. VAR
  302.    Row    : INTEGER;
  303.    Col    : INTEGER;
  304.    RowNow : INTEGER;
  305.  
  306. BEGIN (* Ansi_Set_Cursor *)
  307.                                    (* Get current row position *)
  308.    RowNow := WhereY;
  309.                                    (* Determine new row and column *)
  310.    CASE Escape_Number OF
  311.                                    (* Home cursor if no coords given *)
  312.       0 : BEGIN
  313.              Row := 1;
  314.              Col := 1;
  315.           END;
  316.                                    (* Column 1 is default, row provided *)
  317.       1 : BEGIN
  318.              Col := 1;
  319.              Row := Escape_Register[1];
  320.           END;
  321.                                    (* Both row and column provided *)
  322.       ELSE
  323.              Col := Escape_Register[2];
  324.              Row := Escape_Register[1];
  325.  
  326.    END;
  327.                                    (* Check line attributes *)
  328.  
  329.    Ansi_Check_Line_Attributes( Row );
  330.  
  331.                                    (* Handle origin mode    *)
  332.    IF Origin_Mode THEN
  333.       Row := Row + PRED( Top_Scroll );
  334.        
  335.                                    (* Clip to screen size   *)
  336.  
  337.    Row := MAX( MIN( Row , Ansi_Last_Line ) , 1 );
  338.  
  339.    IF ( NOT Double_Width_Mode ) THEN
  340.       Col := MAX( MIN( Col , Wrap_Screen_Col ) , 1 )
  341.    ELSE
  342.       Col := MAX( MIN( Col , 40 ) , 1 );
  343.  
  344.                                    (* If we moved down 1 line,  *)
  345.                                    (* update the review buffer. *)
  346.    IF ( Row <> RowNow ) THEN
  347.       BEGIN
  348.          Last_Column_Hit := FALSE;
  349.          IF Review_On THEN
  350.             IF ( ORD( Review_Line[0] ) > 0 ) THEN
  351.                Update_Review_Pointers;
  352.       END;
  353.                                    (* Treat as if line written to *)
  354.                                    (* capture file.               *)
  355.    IF Capture_On THEN
  356.       Capture_Char( CHR( LF ) );
  357.  
  358.                                    (* Move to new coordinates *)
  359.    IF Double_Width_Mode THEN
  360.       MoveToXY( 2 * Col - 1 , Row )
  361.    ELSE
  362.       MoveToXY( Col , Row );
  363. {
  364.    IF Debug_Mode THEN
  365.       BEGIN
  366.          Write_Log('Set_Cursor: R=' + IToS( Row ) + ', C=' + IToS( Col ) +
  367.                    ', TS=' + IToS( Top_Scroll ) + ', BS=' +
  368.                    IToS( Bottom_Scroll ), FALSE, FALSE );
  369.          IF Origin_Mode THEN
  370.             Write_Log('    OriginMode=YES', FALSE, FALSE )
  371.          ELSE
  372.             Write_Log('    OriginMode=NO', FALSE, FALSE );
  373.          Write_Log('    UpperLeftRow=' + IToS( Upper_Left_Row ), FALSE, FALSE );
  374.       END;
  375. }
  376. END   (* Ansi_Set_Cursor *);
  377.  
  378. (*----------------------------------------------------------------------*)
  379. (*             Ansi_Clear_Screen --- Clear segment of screen            *)
  380. (*----------------------------------------------------------------------*)
  381.  
  382. PROCEDURE Ansi_Clear_Screen;
  383.  
  384. (*----------------------------------------------------------------------*)
  385. (*                                                                      *)
  386. (*     Procedure: Ansi_Clear_Screen                                     *)
  387. (*                                                                      *)
  388. (*     Purpose:   Clears portion of screen                              *)
  389. (*                                                                      *)
  390. (*     Calling Sequence:                                                *)
  391. (*                                                                      *)
  392. (*        Ansi_Clear_Screen;                                            *)
  393. (*                                                                      *)
  394. (*     Called by:  VT100_Process_Escape                                 *)
  395. (*                 Ansi_Process_Escape                                  *)
  396. (*                                                                      *)
  397. (*----------------------------------------------------------------------*)
  398.  
  399. VAR
  400.    I:        INTEGER;
  401.    X:        INTEGER;
  402.    Y:        INTEGER;
  403.    C:        INTEGER;
  404.  
  405. BEGIN (* Ansi_Clear_Screen *)
  406.                                    (* Update the review buffer. *)
  407.    IF Review_On THEN
  408.       IF ( ORD( Review_Line[0] ) > 0 ) THEN
  409.          Update_Review_Pointers;
  410.                                    (* Update capture file *)
  411.    IF Capture_On THEN
  412.       Capture_Char( CHR( LF ) );
  413.                                    (* Get type of clear to perform *)
  414.    IF ( Escape_Number = 1 )  THEN
  415.       C := Escape_Register[1]
  416.    ELSE
  417.       C := 0;
  418.  
  419.    Save_FG1 := FG;
  420.    Save_BG1 := BG;
  421.  
  422.    IF VT100_Allowed THEN
  423.       Set_Global_Colors( Ansi_ForeGround_Color , Ansi_BackGround_Color );
  424.  
  425.    X     := WhereX;
  426.    Y     := WhereY;
  427.  
  428.    CASE C OF
  429.                                    (* Clear from cursor position to *)
  430.                                    (* end of screen                 *)
  431.       0:  BEGIN
  432.  
  433.              ClrEol;
  434.  
  435.              FOR I := ( Y + 1 ) TO Ansi_Last_Line DO
  436.                 BEGIN
  437.                    GoToXY( 1 , I );
  438.                    ClrEol;
  439.                    Line_Attributes[I] := 0;
  440.                 END;
  441.  
  442.              GoToXY( X , Y );
  443.  
  444.           END;
  445.                                    (* Clear start of screen to current *)
  446.                                    (* cursor position                  *)
  447.       1:  BEGIN
  448.  
  449.              IF ( Y > 1 ) THEN
  450.                 Scroll( 1, Y - 1, 1, Max_Screen_Col, 0, FG, BG );
  451.  
  452.              GoToXY( 1 , Y );
  453.  
  454.              FOR I := 1 TO X DO
  455.                 WRITE(' ');
  456.  
  457.              FOR I := 1 TO Y DO
  458.                 Line_Attributes[I] := 0;
  459.  
  460.           END;
  461.                                    (* Clear entire screen *)
  462.       2:  BEGIN
  463.              Scroll( 1, Ansi_Last_Line, 1, Max_Screen_Col, 0, FG, BG );
  464.              FillChar( Line_Attributes, Max_Screen_Line, 0 );
  465.              IF VT100_Allowed THEN
  466.                 GoToXY( X , Y )
  467.              ELSE
  468.                 GoToXY( 1 , 1 );
  469.           END;
  470.  
  471.    END (* CASE *);
  472.  
  473.    Set_Global_Colors( Save_FG1 , Save_BG1 );
  474.  
  475. END   (* Ansi_Clear_Screen *);
  476.  
  477. (*----------------------------------------------------------------------*)
  478. (*             Ansi_Clear_Line --- Clear part of line in display        *)
  479. (*----------------------------------------------------------------------*)
  480.  
  481. PROCEDURE Ansi_Clear_Line;
  482.  
  483. (*----------------------------------------------------------------------*)
  484. (*                                                                      *)
  485. (*     Procedure: Ansi_Clear_Line                                       *)
  486. (*                                                                      *)
  487. (*     Purpose:   Clears portion of current line                        *)
  488. (*                                                                      *)
  489. (*     Calling Sequence:                                                *)
  490. (*                                                                      *)
  491. (*        Ansi_Clear_Line;                                              *)
  492. (*                                                                      *)
  493. (*     Called by:  VT100_Process_Escape                                 *)
  494. (*                 Ansi_Process_Escape                                  *)
  495. (*                                                                      *)
  496. (*----------------------------------------------------------------------*)
  497.  
  498. VAR
  499.    I:        INTEGER;
  500.    X:        INTEGER;
  501.    Y:        INTEGER;
  502.    C:        INTEGER;
  503.  
  504. BEGIN (* Ansi_Clear_Line *)
  505.  
  506.    IF ( Escape_Number = 1 )  THEN
  507.       C := Escape_Register[1]
  508.    ELSE
  509.       C := 0;
  510.  
  511.    Save_FG1 := FG;
  512.    Save_BG1 := BG;
  513.  
  514.    IF VT100_Allowed THEN
  515.       Set_Global_Colors( Ansi_ForeGround_Color , Ansi_BackGround_Color );
  516.  
  517.                                    (* Remember current position *)
  518.    X := WhereX;
  519.    Y := WhereY;
  520.  
  521.    CASE C OF
  522.                                    (* Clear cursor to end *)
  523.       0:  ClrEol;
  524.                                    (* Clear start to cursor *)
  525.       1:  BEGIN
  526.              GoToXY( 1 , Y );
  527.              FOR I := 1 TO X DO
  528.                 WRITE(' ');
  529.           END;
  530.                                    (* Clear entire line *)
  531.       2:  BEGIN
  532.              GoToXY( 1 , Y );
  533.              ClrEol;
  534.              GoToXY( X , Y );
  535.              Line_Attributes[Y] := 0;
  536.           END;
  537.  
  538.    END  (* CASE *);
  539.  
  540.    Set_Global_Colors( Save_FG1 , Save_BG1 );
  541.  
  542. END   (* Ansi_Clear_Line *);
  543.  
  544. (*----------------------------------------------------------------------*)
  545. (*          Ansi_Write_Escape --- Write out escape sequence to display  *)
  546. (*----------------------------------------------------------------------*)
  547.  
  548. PROCEDURE Ansi_Write_Escape;
  549.  
  550. (*----------------------------------------------------------------------*)
  551. (*                                                                      *)
  552. (*     Procedure: Ansi_Write_Escape                                     *)
  553. (*                                                                      *)
  554. (*     Purpose:   Writes unused escape sequence chars to display        *)
  555. (*                                                                      *)
  556. (*     Calling Sequence:                                                *)
  557. (*                                                                      *)
  558. (*        Ansi_Write_Escape;                                            *)
  559. (*                                                                      *)
  560. (*     Called by:  VT100_Process_Escape                                 *)
  561. (*                 Ansi_Process_Escape                                  *)
  562. (*                                                                      *)
  563. (*----------------------------------------------------------------------*)
  564.  
  565. VAR
  566.    I: INTEGER;
  567.  
  568. BEGIN (* Ansi_Write_Escape *)
  569.  
  570.    FOR I := 1 TO LENGTH( Escape_Str ) DO
  571.       Display_Character( Escape_Str[I] );
  572.  
  573.    Escape_Type    := ' ';
  574.  
  575. END   (* Ansi_Write_Escape *);
  576.  
  577. (*----------------------------------------------------------------------*)
  578. (*            Ansi_Next_Char --- Get next character in escape sequence  *)
  579. (*----------------------------------------------------------------------*)
  580.  
  581. FUNCTION Ansi_Next_Char : CHAR;
  582.  
  583. (*----------------------------------------------------------------------*)
  584. (*                                                                      *)
  585. (*     Function: Ansi_Next_Char                                         *)
  586. (*                                                                      *)
  587. (*     Purpose:  Waits for next character in escape sequence            *)
  588. (*                                                                      *)
  589. (*     Calling Sequence:                                                *)
  590. (*                                                                      *)
  591. (*        Ansi_Next_Char;                                               *)
  592. (*                                                                      *)
  593. (*     Called by:  VT100_Process_Escape                                 *)
  594. (*                 Ansi_Process_Escape                                  *)
  595. (*                                                                      *)
  596. (*     Remarks:                                                         *)
  597. (*                                                                      *)
  598. (*        This routine actually shouldn't be used, but I got lazy.      *)
  599. (*        Needs to be fixed next time around.                           *)
  600. (*                                                                      *)
  601. (*----------------------------------------------------------------------*)
  602.  
  603. VAR
  604.    Next_Ch: INTEGER;
  605.  
  606. BEGIN (* Ansi_Next_Char *)
  607.  
  608.    Async_Receive_With_Timeout( 5 , Next_Ch );
  609.  
  610.    IF Next_Ch > 0 THEN
  611.       Ansi_Next_Char := CHR( Next_Ch )
  612.    ELSE
  613.       Ansi_Next_Char := CHR( 0 );
  614.  
  615. END   (* Ansi_Next_Char *);
  616.  
  617. (*----------------------------------------------------------------------*)
  618. (*      Ansi_Set_Scrolling_Region --- Set scrolling region (window)     *)
  619. (*----------------------------------------------------------------------*)
  620.  
  621. PROCEDURE Ansi_Set_Scrolling_Region;
  622.  
  623. (*----------------------------------------------------------------------*)
  624. (*                                                                      *)
  625. (*     Procedure: Ansi_Set_Scrolling_Region                             *)
  626. (*                                                                      *)
  627. (*     Purpose:   Sets scrolling region (window)                        *)
  628. (*                                                                      *)
  629. (*     Calling Sequence:                                                *)
  630. (*                                                                      *)
  631. (*        Ansi_Set_Scrolling_Region;                                    *)
  632. (*                                                                      *)
  633. (*     Called by:  VT100_Process_Escape                                 *)
  634. (*                 Ansi_Process_Escape                                  *)
  635. (*                                                                      *)
  636. (*----------------------------------------------------------------------*)
  637.  
  638. VAR
  639.    Top:    INTEGER;
  640.    Bottom: INTEGER;
  641.  
  642. BEGIN (* Ansi_Set_Scrolling_Region *)
  643.  
  644.    CASE Escape_Number OF
  645.                                    (* Window is entire screen *)
  646.       0:  BEGIN
  647.              Top    := 1;
  648.              Bottom := Ansi_Last_Line;
  649.           END;
  650.                                    (* From specified line to end of screen *)
  651.       1:  BEGIN
  652.              Top    := MAX( Escape_Register[1] , 1 );
  653.              Bottom := Ansi_Last_Line;
  654.           END;
  655.                                    (* Both top and bottom specified *)
  656.       2:  BEGIN
  657.              Top    := MAX( Escape_Register[1] , 1  );
  658.              Bottom := MIN( Escape_Register[2] , Ansi_Last_Line );
  659.           END;
  660.  
  661.       ELSE
  662.              Top    := MAX( Escape_Register[1] , 1  );
  663.              Bottom := MIN( Escape_Register[2] , Ansi_Last_Line );
  664.  
  665.    END (* CASE *);
  666.  
  667.    IF Bottom < Top THEN Bottom := Ansi_Last_Line;
  668.    IF Bottom = 0   THEN Bottom := Ansi_Last_Line;
  669.  
  670.    IF Origin_Mode THEN
  671.       Window( 1, Top, Max_Screen_Col, Bottom );
  672.  
  673.    GoToXY( 1 , 1 );
  674.  
  675.    Top_Scroll    := Top;
  676.    Bottom_Scroll := Bottom;
  677.  
  678.    IF Origin_Mode THEN
  679.       Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  680.  
  681. END   (* Ansi_Set_Scrolling_Region *);
  682.  
  683. (*----------------------------------------------------------------------*)
  684. (*                    Ansi_Cursor_Up --- Move cursor up                 *)
  685. (*----------------------------------------------------------------------*)
  686.  
  687. PROCEDURE Ansi_Cursor_Up;
  688.  
  689. (*----------------------------------------------------------------------*)
  690. (*                                                                      *)
  691. (*     Procedure: Ansi_Cursor_Up;                                       *)
  692. (*                                                                      *)
  693. (*     Purpose:   Moves cursor up specified number of lines             *)
  694. (*                                                                      *)
  695. (*     Calling Sequence:                                                *)
  696. (*                                                                      *)
  697. (*        Ansi_Cursor_Up;                                               *)
  698. (*                                                                      *)
  699. (*     Called by:  VT100_Process_Escape                                 *)
  700. (*                                                                      *)
  701. (*----------------------------------------------------------------------*)
  702.  
  703. VAR
  704.    Y    : INTEGER;
  705.    X    : INTEGER;
  706.    Regs : RegPack;
  707.  
  708. BEGIN (* Ansi_Cursor_Up *)
  709.                                    (* Get current position.  If not in *)
  710.                                    (* scrolling region, we do nothing. *)
  711.    Regs.Ah            := 3;
  712.    Regs.Bh            := 0;
  713.    INTR( $10 , Regs );
  714.  
  715.    X := SUCC( Regs.Dl );
  716.    Y := SUCC( Regs.Dh );
  717. {
  718.    IF ( ( Y > Bottom_Scroll ) OR ( Y <= Top_Scroll ) ) THEN
  719.       EXIT;
  720. }
  721.    IF ( Y < Top_Scroll ) THEN
  722.       EXIT;
  723.                                    (* Get # of lines to move up *)
  724.    IF Escape_Number = 0 THEN
  725.       Reg_Val := 1
  726.    ELSE
  727.       Reg_Val := MAX( 1 , Escape_Register[1] );
  728.  
  729.    Set_Cursor( X , MAX( Y - Reg_Val , Top_Scroll ) );
  730.  
  731.    IF ( WhereY <> Y ) THEN
  732.       Last_Column_Hit := FALSE;
  733.  
  734. END   (* Ansi_Cursor_Up *);
  735.  
  736. (*----------------------------------------------------------------------*)
  737. (*                 Ansi_Cursor_Down --- Move cursor down                *)
  738. (*----------------------------------------------------------------------*)
  739.  
  740. PROCEDURE Ansi_Cursor_Down;
  741.  
  742. (*----------------------------------------------------------------------*)
  743. (*                                                                      *)
  744. (*     Procedure: Ansi_Cursor_Down;                                     *)
  745. (*                                                                      *)
  746. (*     Purpose:   Moves cursor down specified number of lines           *)
  747. (*                                                                      *)
  748. (*     Calling Sequence:                                                *)
  749. (*                                                                      *)
  750. (*        Ansi_Cursor_Down;                                             *)
  751. (*                                                                      *)
  752. (*     Called by:  VT100_Process_Escape                                 *)
  753. (*                                                                      *)
  754. (*----------------------------------------------------------------------*)
  755.  
  756. VAR
  757.    Y    : INTEGER;
  758.    X    : INTEGER;
  759.    Regs : RegPack;
  760.  
  761. BEGIN (* Ansi_Cursor_Down *)
  762.                                    (* Get current position.  If not in *)
  763.                                    (* scrolling region, we do nothing. *)
  764.    Regs.Ah            := 3;
  765.    Regs.Bh            := 0;
  766.    INTR( $10 , Regs );
  767.  
  768.    X := SUCC( Regs.Dl );
  769.    Y := SUCC( Regs.Dh );
  770. {
  771.    IF ( ( Y >= Bottom_Scroll ) OR ( Y < Top_Scroll ) ) THEN
  772. }
  773.    IF ( Y >= Bottom_Scroll ) THEN
  774.       EXIT;
  775.                                    (* Get # of lines to move down *)
  776.    IF Escape_Number = 0 THEN
  777.       Reg_Val := 1
  778.    ELSE
  779.       Reg_Val := MAX( 1 , Escape_Register[1] );
  780.  
  781.    Set_Cursor( X, MIN( Y + Reg_Val , Bottom_Scroll ) );
  782.  
  783.    IF ( WhereY <> Y ) THEN
  784.       Last_Column_Hit := FALSE;
  785.  
  786. END   (* Ansi_Cursor_Down *);
  787.  
  788. (*----------------------------------------------------------------------*)
  789. (*                  Ansi_Cursor_Left --- Move cursor left               *)
  790. (*----------------------------------------------------------------------*)
  791.  
  792. PROCEDURE Ansi_Cursor_Left;
  793.  
  794. (*----------------------------------------------------------------------*)
  795. (*                                                                      *)
  796. (*     Procedure: Ansi_Cursor_Left;                                     *)
  797. (*                                                                      *)
  798. (*     Purpose:   Moves cursor left specified number of columns         *)
  799. (*                                                                      *)
  800. (*     Calling Sequence:                                                *)
  801. (*                                                                      *)
  802. (*        Ansi_Cursor_Left;                                             *)
  803. (*                                                                      *)
  804. (*     Called by:  VT100_Process_Escape                                 *)
  805. (*                                                                      *)
  806. (*----------------------------------------------------------------------*)
  807.  
  808. BEGIN (* Ansi_Cursor_Left *)
  809.  
  810.    IF Escape_Number = 0 THEN
  811.       Reg_Val := 1
  812.    ELSE
  813.       Reg_Val := MAX( 1 , Escape_Register[1] );
  814.  
  815.    Set_Cursor( MAX( WhereX - Reg_Val , 1 ), WhereY );
  816.  
  817. END   (* Ansi_Cursor_Left *);
  818.  
  819. (*----------------------------------------------------------------------*)
  820. (*                 Ansi_Cursor_Right --- Move cursor right              *)
  821. (*----------------------------------------------------------------------*)
  822.  
  823. PROCEDURE Ansi_Cursor_Right;
  824.  
  825. (*----------------------------------------------------------------------*)
  826. (*                                                                      *)
  827. (*     Procedure: Ansi_Cursor_Right;                                    *)
  828. (*                                                                      *)
  829. (*     Purpose:   Moves cursor right specified number of columns        *)
  830. (*                                                                      *)
  831. (*     Calling Sequence:                                                *)
  832. (*                                                                      *)
  833. (*        Ansi_Cursor_Right;                                            *)
  834. (*                                                                      *)
  835. (*     Called by:  VT100_Process_Escape                                 *)
  836. (*                                                                      *)
  837. (*----------------------------------------------------------------------*)
  838.  
  839. BEGIN (* Ansi_Cursor_Right *)
  840.  
  841.    IF Escape_Number = 0 THEN
  842.       Reg_Val := 1
  843.    ELSE
  844.       Reg_Val := MAX( 1 , Escape_Register[1] );
  845.  
  846.    Set_Cursor( MIN( WhereX + Reg_Val , Wrap_Screen_Col ), WhereY );
  847.  
  848. END   (* Ansi_Cursor_Right *);
  849.  
  850. (*----------------------------------------------------------------------*)
  851. (*              Ansi_Status_Report --- Provide terminal status          *)
  852. (*----------------------------------------------------------------------*)
  853.  
  854. PROCEDURE Ansi_Status_Report;
  855.  
  856. (*----------------------------------------------------------------------*)
  857. (*                                                                      *)
  858. (*     Procedure: Ansi_Status_Report;                                   *)
  859. (*                                                                      *)
  860. (*     Purpose:   Provides status reports to host enquiries             *)
  861. (*                                                                      *)
  862. (*     Calling Sequence:                                                *)
  863. (*                                                                      *)
  864. (*        Ansi_Status_Report;                                           *)
  865. (*                                                                      *)
  866. (*     Called by:  VT100_Process_Escape                                 *)
  867. (*                                                                      *)
  868. (*----------------------------------------------------------------------*)
  869.  
  870. VAR
  871.    Istatus  : INTEGER;
  872.    C_Column : STRING[10];
  873.    C_Row    : STRING[10];
  874.  
  875. BEGIN (* Ansi_Status_Report *)
  876.  
  877.    IF Escape_Number = 0 THEN
  878.       Istatus := 5
  879.    ELSE
  880.       Istatus := Escape_Register[ 1 ];
  881.  
  882.    CASE Istatus OF
  883.  
  884.       5:    Async_Send_String( CHR( 27 ) + '[0n' );
  885.  
  886.       6:    BEGIN
  887.                STR( WhereX, C_Column );
  888.                STR( WhereY, C_Row    );
  889.                Async_Send_String( CHR( 27 ) + '[' +
  890.                                   C_Row + ';' + C_Column + 'R' );
  891.             END;
  892.  
  893.       ELSE;
  894.  
  895.    END   (* CASE *);
  896.  
  897. END   (* Ansi_Status_Report *);
  898.  
  899. (*----------------------------------------------------------------------*)
  900. (*              Ansi_Swap_Colors --- Swap foreground/background colors  *)
  901. (*----------------------------------------------------------------------*)
  902.  
  903. PROCEDURE Ansi_Swap_Colors;
  904.  
  905. VAR
  906.    K: INTEGER;
  907.  
  908. BEGIN (* Ansi_Swap_Colors *)
  909.  
  910.    K                     := Ansi_ForeGround_Color;
  911.    Ansi_ForeGround_Color := Ansi_BackGround_Color;
  912.    Ansi_BackGround_Color := K;
  913.  
  914.    K                := ForeGround_Color;
  915.    ForeGround_Color := BackGround_Color;
  916.    BackGround_Color := K;
  917.  
  918.    K  := FG;
  919.    FG := BG;
  920.    BG := K;
  921.  
  922.    Set_Global_Colors( ForeGround_Color , BackGround_Color );
  923.    Set_Border_Color ( BackGround_Color );
  924.  
  925.    Status_Line_Attr := 16 * ( ForeGround_Color AND 7 ) +
  926.                        BackGround_Color;
  927.  
  928. END   (* Ansi_Swap_Colors *);
  929.  
  930. (*----------------------------------------------------------------------*)
  931. (*              Ansi_Set_Mode --- Set a terminal mode                   *)
  932. (*----------------------------------------------------------------------*)
  933.  
  934. PROCEDURE Ansi_Set_Mode( Mode_Type : CHAR );
  935.  
  936. (*----------------------------------------------------------------------*)
  937. (*                                                                      *)
  938. (*     Procedure: Ansi_Set_Mode;                                        *)
  939. (*                                                                      *)
  940. (*     Purpose:   Set a terminal mode                                   *)
  941. (*                                                                      *)
  942. (*     Calling Sequence:                                                *)
  943. (*                                                                      *)
  944. (*        Ansi_Set_Mode( Mode_Type : CHAR );                            *)
  945. (*                                                                      *)
  946. (*           Mode_Type --- ' ' or '?' depending upon type of            *)
  947. (*                         parameter to set.                            *)
  948. (*                                                                      *)
  949. (*     Called by:  VT100_Process_Escape                                 *)
  950. (*                                                                      *)
  951. (*----------------------------------------------------------------------*)
  952.  
  953. VAR
  954.    I    : INTEGER;
  955.    Regs : RegPack;
  956.  
  957. BEGIN (* Ansi_Set_Mode *)
  958.  
  959.    IF ( Mode_Type = '?' ) THEN
  960.       FOR I := 1 TO Escape_Number DO
  961.  
  962.          CASE Escape_Register[I] OF
  963.  
  964.             1:    IF Auto_Change_Arrows THEN
  965.                      BEGIN
  966.                         IF ( Key_Definitions[U_Arrow].Def = NIL ) THEN
  967.                            NEW( Key_Definitions[U_Arrow].Def );
  968.                         Key_Definitions[U_Arrow].Def^ := CHR( ESC ) + 'OA';
  969.                         IF ( Key_Definitions[D_Arrow].Def = NIL ) THEN
  970.                            NEW( Key_Definitions[D_Arrow].Def );
  971.                         Key_Definitions[D_Arrow].Def^ := CHR( ESC ) + 'OB';
  972.                         IF ( Key_Definitions[L_Arrow].Def = NIL ) THEN
  973.                            NEW( Key_Definitions[L_Arrow].Def );
  974.                         Key_Definitions[L_Arrow].Def^ := CHR( ESC ) + 'OD';
  975.                         IF ( Key_Definitions[R_Arrow].Def = NIL ) THEN
  976.                            NEW( Key_Definitions[R_Arrow].Def );
  977.                         Key_Definitions[R_Arrow].Def^ := CHR( ESC ) + 'OC';
  978.                      END;
  979.  
  980.             3:    BEGIN
  981.                      IF ATI_Ega_Wonder THEN
  982.                         BEGIN
  983.                            Regs.AX := $23;
  984.                            INTR( $10, Regs );
  985.                            Max_Screen_Col  := 132;
  986.                            Max_Screen_Line := 25;
  987.                            Set_Screen_Size( 25 , 132 );
  988.                            IF Do_Status_Line THEN
  989.                               BEGIN
  990.                                  Set_Status_Line_Name(Short_Terminal_Name);
  991.                                  Write_To_Status_Line( Status_Line_Name, 1 );
  992.                               END;
  993.                            Last_Column_Hit := FALSE;
  994.                         END;
  995.                      Width_132          := TRUE;
  996.                      Wrap_Screen_Col    := MIN( Max_Screen_Col , 132 );
  997.                      Escape_Number      := 1;
  998.                      Escape_Register[1] := 2;
  999.                      Ansi_Clear_Screen;
  1000.                      GoToXY( 1 , 1 );
  1001.                      EXIT;
  1002.                   END;
  1003.  
  1004.             5:    IF ( NOT Reverse_On ) THEN
  1005.                      BEGIN
  1006.                         Ansi_Swap_Colors;
  1007.                         Set_Text_Attributes( 1, 1, Max_Screen_Col,
  1008.                                              Max_Screen_Line - 1,
  1009.                                              Ansi_Foreground_Color,
  1010.                                              Ansi_BackGround_Color );
  1011.                         Reverse_On := TRUE;
  1012.                         IF Do_Status_Line THEN
  1013.                            Write_To_Status_Line( Status_Line_Name, 1 );
  1014.                      END;
  1015.  
  1016.             6:    BEGIN
  1017.                      Origin_Mode := ON;
  1018.                      Window( 1, Top_Scroll, Max_Screen_Col, Bottom_Scroll );
  1019.                      GoToXY( 1 , 1 );
  1020.                      Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  1021.                   END;
  1022.  
  1023.             7:    Auto_Wrap_Mode := ON;
  1024.  
  1025.             12:   Local_Echo     := ON;
  1026.  
  1027.             ELSE;
  1028.  
  1029.          END   (* CASE *)
  1030.    ELSE
  1031.       FOR I := 1 TO Escape_Number DO
  1032.  
  1033.          CASE Escape_Register[I] OF
  1034.  
  1035.              2:   (* Keyboard_Locked := ON *);
  1036.              4:   Insertion_Mode := ON;
  1037.             20:   New_Line       := ON;
  1038.             ELSE;
  1039.  
  1040.          END   (* CASE *);
  1041.  
  1042. END   (* Ansi_Set_Mode *);
  1043.  
  1044. (*----------------------------------------------------------------------*)
  1045. (*            Ansi_Reset_Mode --- Reset a terminal mode                 *)
  1046. (*----------------------------------------------------------------------*)
  1047.  
  1048. PROCEDURE Ansi_Reset_Mode( Mode_Type : CHAR; VAR Done: BOOLEAN );
  1049.  
  1050. (*----------------------------------------------------------------------*)
  1051. (*                                                                      *)
  1052. (*     Procedure: Ansi_Reset_Mode;                                      *)
  1053. (*                                                                      *)
  1054. (*     Purpose:   Resets a terminal mode                                *)
  1055. (*                                                                      *)
  1056. (*     Calling Sequence:                                                *)
  1057. (*                                                                      *)
  1058. (*        Ansi_Reset_Mode( Mode_Type : CHAR; VAR Done : BOOLEAN );      *)
  1059. (*                                                                      *)
  1060. (*           Mode_Type --- ' ' or '?' depending upon type of            *)
  1061. (*                         parameter to set.                            *)
  1062. (*           Done      --- TRUE if switch to VT52 done.                 *)
  1063. (*                                                                      *)
  1064. (*     Called by:  VT100_Process_Escape                                 *)
  1065. (*                                                                      *)
  1066. (*----------------------------------------------------------------------*)
  1067.  
  1068. VAR
  1069.    I : INTEGER;
  1070.    B : BOOLEAN;
  1071.    Ch: CHAR;
  1072.    Regs : RegPack;
  1073.  
  1074. BEGIN (* Ansi_Reset_Mode *)
  1075.  
  1076.    IF ( Mode_Type = '?' ) THEN
  1077.       FOR I := 1 TO Escape_Number DO
  1078.  
  1079.          CASE Escape_Register[I] OF
  1080.  
  1081.             1:    IF Auto_Change_Arrows THEN
  1082.                      BEGIN
  1083.                         IF ( Key_Definitions[U_Arrow].Def = NIL ) THEN
  1084.                            NEW( Key_Definitions[U_Arrow].Def );
  1085.                         Key_Definitions[U_Arrow].Def^ := CHR( ESC ) + '[A';
  1086.                         IF ( Key_Definitions[D_Arrow].Def = NIL ) THEN
  1087.                            NEW( Key_Definitions[D_Arrow].Def );
  1088.                         Key_Definitions[D_Arrow].Def^ := CHR( ESC ) + '[B';
  1089.                         IF ( Key_Definitions[L_Arrow].Def = NIL ) THEN
  1090.                            NEW( Key_Definitions[L_Arrow].Def );
  1091.                         Key_Definitions[L_Arrow].Def^ := CHR( ESC ) + '[D';
  1092.                         IF ( Key_Definitions[R_Arrow].Def = NIL ) THEN
  1093.                            NEW( Key_Definitions[R_Arrow].Def );
  1094.                         Key_Definitions[R_Arrow].Def^ := CHR( ESC ) + '[C';
  1095.                      END;
  1096.  
  1097.                                    (* We cheat here in order to avoid        *)
  1098.                                    (* an unnecessary switch in the case      *)
  1099.                                    (* of ESC [?2l being followed immediately *)
  1100.                                    (* by ESC < -- i.e., return to ANSI mode. *)
  1101.             2:    BEGIN
  1102.                      DELAY( Tenth_Of_A_Second_Delay );
  1103.                      IF ( Async_Peek( 0 ) = CHR( ESC ) ) AND
  1104.                         ( Async_Peek( 1 ) = '<'        ) THEN
  1105.                         BEGIN
  1106.                            Graphics_Mode := FALSE;
  1107.                            B             := Async_Receive( Ch );
  1108.                            B             := Async_Receive( Ch );
  1109.                         END
  1110.                      ELSE
  1111.                         BEGIN
  1112.                            Terminal_To_Emulate := VT52;
  1113.                            Done                := TRUE;
  1114.                         END;
  1115.                   END;
  1116.  
  1117.             3:    BEGIN
  1118.                      IF ATI_Ega_Wonder THEN
  1119.                         BEGIN
  1120.                            Max_Screen_Col  := 80;
  1121.                            Max_Screen_Line := 25;
  1122.                            Regs.AX := $03;
  1123.                            INTR( $10, Regs );
  1124.                            Set_Screen_Size( 25 , 80 );
  1125.                            IF Do_Status_Line THEN
  1126.                               BEGIN
  1127.                                  Set_Status_Line_Name(Short_Terminal_Name);
  1128.                                  Write_To_Status_Line( Status_Line_Name, 1 );
  1129.                               END;
  1130.                            Last_Column_Hit := FALSE;
  1131.                            Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  1132.                            GoToXY( 1 , 1 );
  1133. {
  1134.                            Set_EGA_Text_Mode( Max_Screen_Line );
  1135.                            CursorOn;
  1136. }
  1137.                         END;
  1138.                      Width_132          := FALSE;
  1139.                      Wrap_Screen_Col    := MIN( Max_Screen_Col , 80 );
  1140.                      Escape_Number      := 1;
  1141.                      Escape_Register[1] := 2;
  1142.                      Ansi_Clear_Screen;
  1143.                      GoToXY( 1 , 1 );
  1144.                      EXIT;
  1145.                   END;
  1146.  
  1147.             5:    IF Reverse_On THEN
  1148.                      BEGIN
  1149.                         Ansi_Swap_Colors;
  1150.                         Set_Text_Attributes( 1, 1, Max_Screen_Col,
  1151.                                              Max_Screen_Line - 1,
  1152.                                              Ansi_Foreground_Color,
  1153.                                              Ansi_BackGround_Color );
  1154.                         Reverse_On := FALSE;
  1155.                         IF Do_Status_Line THEN
  1156.                            Write_To_Status_Line( Status_Line_Name, 1 );
  1157.                      END;
  1158.  
  1159.             6:    BEGIN
  1160.                      Origin_Mode := OFF;
  1161.                      Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  1162.                      GoToXY( 1 , 1 );
  1163.                   END;
  1164.  
  1165.             7:    Auto_Wrap_Mode := OFF;
  1166.  
  1167.             12:   Local_Echo     := OFF;
  1168.  
  1169.             ELSE;
  1170.  
  1171.          END   (* CASE *)
  1172.    ELSE
  1173.       FOR I := 1 TO Escape_Number DO
  1174.  
  1175.          CASE Escape_Register[I] OF
  1176.  
  1177.              2:   (* Keyboard_Locked := OFF *);
  1178.              4:   Insertion_Mode := OFF;
  1179.             20:   New_Line       := OFF;
  1180.             ELSE;
  1181.  
  1182.          END   (* CASE *);
  1183.  
  1184. END   (* Ansi_Reset_Mode *);
  1185.  
  1186. (*----------------------------------------------------------------------*)
  1187. (*         Ansi_Printer_Control --- Sets printer control modes          *)
  1188. (*----------------------------------------------------------------------*)
  1189.  
  1190. PROCEDURE Ansi_Printer_Control( Mode_Type : CHAR );
  1191.  
  1192. (*----------------------------------------------------------------------*)
  1193. (*                                                                      *)
  1194. (*     Procedure: Ansi_Printer_Control;                                 *)
  1195. (*                                                                      *)
  1196. (*     Purpose:   Sets printer control modes                            *)
  1197. (*                                                                      *)
  1198. (*     Calling Sequence:                                                *)
  1199. (*                                                                      *)
  1200. (*        Ansi_Printer_Control;                                         *)
  1201. (*                                                                      *)
  1202. (*           Mode_Type --- ' ' or '?' depending upon type of            *)
  1203. (*                         parameter to set.                            *)
  1204. (*                                                                      *)
  1205. (*     Called by:  VT100_Process_Escape                                 *)
  1206. (*                                                                      *)
  1207. (*----------------------------------------------------------------------*)
  1208.  
  1209. VAR
  1210.    SaveM     : INTEGER;
  1211.    Text_Line : AnyStr;
  1212.  
  1213. BEGIN (* Ansi_Printer_Control *)
  1214.  
  1215.    IF ( Escape_Number = 0 ) THEN
  1216.       Escape_Register[1] := 0;
  1217.  
  1218.    CASE Mode_Type OF
  1219.  
  1220.       ' ': CASE Escape_Register[1] OF
  1221.               0: BEGIN (* Print screen *)
  1222.                     SaveM           := Max_Screen_Line;
  1223.                     Max_Screen_Line := Ansi_Last_Line;
  1224.                     Print_Screen;
  1225.                     Max_Screen_Line := SaveM;
  1226.                  END   (* Print screen *);
  1227.               4: Printer_Ctrl_Mode := OFF;
  1228.               5: Printer_Ctrl_Mode := ON;
  1229.            END (* CASE *);
  1230.  
  1231.       '?': CASE Escape_Register[1] OF
  1232.               1: BEGIN (* Print current line *)
  1233.                     Get_Screen_Text_Line( Text_Line,
  1234.                                           WhereY + Upper_Left_Row - 1, 1 );
  1235.                     WRITELN( Lst , Text_Line );
  1236.                  END   (* Print current line *);
  1237.               4: Auto_Print_Mode := OFF;
  1238.               5: Auto_Print_Mode := ON;
  1239.            END (* CASE *);
  1240.  
  1241.    END (* CASE *);
  1242.  
  1243. END   (* Ansi_Printer_Control *);
  1244.  
  1245. (*----------------------------------------------------------------------*)
  1246. (*            VT100_Set_Tab --- Sets a tab stop in VT100 mode           *)
  1247. (*----------------------------------------------------------------------*)
  1248.  
  1249. PROCEDURE VT100_Set_Tab;
  1250.  
  1251. (*----------------------------------------------------------------------*)
  1252. (*                                                                      *)
  1253. (*     Procedure: VT100_Set_Tab;                                        *)
  1254. (*                                                                      *)
  1255. (*     Purpose:   Sets tab stop in VT100 mode                           *)
  1256. (*                                                                      *)
  1257. (*     Calling Sequence:                                                *)
  1258. (*                                                                      *)
  1259. (*        VT100_Set_Tab;                                                *)
  1260. (*                                                                      *)
  1261. (*     Called by:  VT100_Process_Escape                                 *)
  1262. (*                                                                      *)
  1263. (*----------------------------------------------------------------------*)
  1264.  
  1265. VAR
  1266.    ITab   : INTEGER;
  1267.    JTab   : INTEGER;
  1268.    TabCol : INTEGER;
  1269.    KTab   : INTEGER;
  1270.  
  1271. BEGIN (* VT100_Set_Tab *)
  1272.  
  1273.    TabCol := WhereX;
  1274.    ITab   := 0;
  1275.  
  1276.    IF ( Number_VT100_Tabs = 0 ) THEN
  1277.       BEGIN
  1278.          Number_VT100_Tabs  := 1;
  1279.          VT100_Tabs[1]      := TabCol;
  1280.          VT100_Tabs[2]      := Wrap_Screen_Col;
  1281.       END
  1282.    ELSE
  1283.       BEGIN
  1284.  
  1285.          REPEAT
  1286.             ITab := SUCC( ITab );
  1287.          UNTIL ( ITab >= Number_VT100_Tabs  ) OR
  1288.                ( VT100_Tabs[ITab] >= TabCol );
  1289.  
  1290.          IF ( VT100_Tabs[ITab] <> TabCol ) THEN
  1291.             BEGIN
  1292.  
  1293.                IF ( VT100_Tabs[ITab] < TabCol ) THEN
  1294.                   KTab := SUCC( ITab )
  1295.                ELSE
  1296.                   KTab := ITab;
  1297.  
  1298.                FOR JTab := Number_VT100_Tabs DOWNTO KTab DO
  1299.                   VT100_Tabs[JTab + 1] := VT100_Tabs[JTab];
  1300.  
  1301.                Number_VT100_Tabs := SUCC( Number_VT100_Tabs );
  1302.  
  1303.                VT100_Tabs[KTab]  := TabCol;
  1304.  
  1305.             END;
  1306.  
  1307.       END;
  1308.  
  1309. END   (* VT100_Set_Tab *);
  1310.  
  1311. (*----------------------------------------------------------------------*)
  1312. (*        VT100_Clear_Tabs --- Clears tab stops in VT100 mode           *)
  1313. (*----------------------------------------------------------------------*)
  1314.  
  1315. PROCEDURE VT100_Clear_Tabs;
  1316.  
  1317. (*----------------------------------------------------------------------*)
  1318. (*                                                                      *)
  1319. (*     Procedure: VT100_Clear_Tabs;                                     *)
  1320. (*                                                                      *)
  1321. (*     Purpose:   Clears one or all tab stops in VT100 mode             *)
  1322. (*                                                                      *)
  1323. (*     Calling Sequence:                                                *)
  1324. (*                                                                      *)
  1325. (*        VT100_Clear_Tabs;                                             *)
  1326. (*                                                                      *)
  1327. (*     Called by:  VT100_Process_Escape                                 *)
  1328. (*                                                                      *)
  1329. (*----------------------------------------------------------------------*)
  1330.  
  1331. VAR
  1332.    ITab   : INTEGER;
  1333.    JTab   : INTEGER;
  1334.    TabCol : INTEGER;
  1335.  
  1336. BEGIN (* VT100_Clear_Tabs *)
  1337.  
  1338.    IF ( Number_VT100_Tabs > 0 ) THEN
  1339.       IF ( Escape_Register[1] = 3 ) THEN
  1340.          BEGIN
  1341.             Number_VT100_Tabs := 0;
  1342.             VT100_Tabs[1]     := Wrap_Screen_Col;
  1343.          END
  1344.       ELSE IF ( Escape_Register[1] = 0 ) THEN
  1345.          BEGIN
  1346.  
  1347.             TabCol := WhereX;
  1348.             ITab   := 0;
  1349.  
  1350.             REPEAT
  1351.                ITab := SUCC( ITab );
  1352.             UNTIL ( ITab >= Number_VT100_Tabs ) OR
  1353.                   ( VT100_Tabs[ITab] >= TabCol );
  1354.  
  1355.             IF ( VT100_Tabs[ITab] = TabCol ) THEN
  1356.                BEGIN
  1357.                   FOR JTab := ITab TO Number_VT100_Tabs DO
  1358.                      VT100_Tabs[JTab] := VT100_Tabs[SUCC( JTab )];
  1359.                   Number_VT100_Tabs := PRED( Number_VT100_Tabs );
  1360.                END;
  1361.  
  1362.          END;
  1363.  
  1364. END   (* VT100_Clear_Tabs *);
  1365.  
  1366.